package cluedo.gui;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.text.*;
import java.util.Date;
import java.util.LinkedList;
import java.text.SimpleDateFormat;

import cluedo.Card;
import cluedo.Player;
import cluedo.Zombie;

import static cluedo.Player.log;



public class EastPanel extends JPanel implements ActionListener, KeyListener{


	private static final long serialVersionUID = 338690859769627212L;
	
	/**
	 * Il giocatore associato alla MainWindow che contiene l'EastPanel
	 */
	private Player myPlayer=null;
	
	/**
	 * L'area in cui sono visualizzati i nickname
	 */
	private NicknamesArea nicknames;
	
	/**
	 * L'area della chat
	 */
	private JTextPane chat;
	
	/**
	 * il campo di input della chat
	 */
	private JTextField chatInput;
	
	/**
	 * Il tasto che invia il messaggio di chat
	 */
	private JButton chatSendButton;
	
	/**
	 * La MainWindow associata all'EastPanel
	 */
	private MainWindow wind;
	
	/**
	 * Il JPanel che contiene le carte che ho in mano
	 */
	private JPanel pageStart;
	
	/**
	 * Variabile per dimensionare carte del giocatore
	 */
	private final int SCALECARD=100;
	
	/**
	 * Spazio tra le carte del giocatore
	 */
	private final int SPACEBETWCARDS=10;
	
	/**
	 * Spazio per separare le sezioni carte, nickname e chat
	 */
	private final int SPACEBETWSECT=20;
	
	
	/**
	 * Il tasto soluzione
	 */
	private JButton assumptSolBtn;
	
	
	/**
	 * Il tasto ipotesi
	 */
	private JButton endTurnBtn;
	
	
	/**
	 * Il dado
	 */
	private Dice dice;
	
	
	/**
	 * timer che gestisce lampeggiamento tasti
	 */
	
	private Timer timer;
	
		
	/**
	 * Crea l'EastPanel
	 * @param player il giocatore associato alla MainWindow wind
	 * @param win la MainWindow che contiene l'EastPanel
	 */
	public EastPanel(Player player, MainWindow wind) {
				
		
		this.wind =wind;
		
		this.myPlayer=player;
		
		log.printLog("EastPanel: creazione pannello east");
		
		this.setBackground(Color.BLACK);
		
		this.setLayout(new BorderLayout());
		
		JPanel outsideSpace = new JPanel();
		
		outsideSpace.setBackground(Color.BLACK);
		
		outsideSpace.setLayout(new BoxLayout(outsideSpace, BoxLayout.X_AXIS));
		
		JPanel outsidePane = new JPanel();
		
		outsidePane.setBackground(Color.BLACK);
		
		outsidePane.setLayout(new BorderLayout());
		
		JPanel btnPane = new JPanel();
		
		btnPane.setLayout(new BoxLayout(btnPane, BoxLayout.Y_AXIS));
		
		btnPane.setBackground(Color.GRAY);
					
		dice=new Dice();
		
		JPanel dicePane = new JPanel();
		
		dicePane.setBackground(Color.GRAY);
			
		dicePane.setLayout(new BoxLayout(dicePane, BoxLayout.X_AXIS));
		
		//dice.setBorderPainted(false);
		
		JPanel wrapDice= new JPanel();
				
		wrapDice.setBackground(Color.GRAY);
		
		Cursor handCurs = new Cursor(Cursor.HAND_CURSOR);
		dice.setCursor(handCurs);
		dice.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		dice.addActionListener(wind);
		dice.setActionCommand("Dado");
		
		
		assumptSolBtn= new JButton("  Soluzione  ");
		assumptSolBtn.setForeground(Color.WHITE);
		assumptSolBtn.setBackground(Color.DARK_GRAY);
		assumptSolBtn.setFont(new Font("Tahoma",Font.BOLD,12));
		assumptSolBtn.setCursor(handCurs);
		assumptSolBtn.setBorder(BorderFactory.createLineBorder(assumptSolBtn.getBackground(),5));
		assumptSolBtn.addActionListener(wind);
		assumptSolBtn.setActionCommand("Soluzione");
		assumptSolBtn.setAlignmentX(CENTER_ALIGNMENT);
		
		
		endTurnBtn= new JButton("  Fine Turno  ");
		endTurnBtn.setForeground(Color.WHITE);
		endTurnBtn.setBackground(Color.DARK_GRAY);
		endTurnBtn.setFont(new Font("Tahoma",Font.BOLD,12));
		endTurnBtn.setCursor(handCurs);
		endTurnBtn.addActionListener(wind);
		endTurnBtn.setBorder(BorderFactory.createLineBorder(endTurnBtn.getBackground(),5));
		endTurnBtn.setActionCommand("FineTurno");
		endTurnBtn.setAlignmentX(CENTER_ALIGNMENT);
		
		btnPane.add(Box.createRigidArea(new Dimension(0,4)));
		btnPane.add(assumptSolBtn);
		btnPane.add(Box.createRigidArea(new Dimension(0,8)));
		btnPane.add(endTurnBtn);
		btnPane.add(Box.createRigidArea(new Dimension(0,4)));
		
		TitledBorder title;
		
		Color myColor=myPlayer.getPlayerColor(myPlayer.getNickname());
		
		title = BorderFactory.createTitledBorder(
				BorderFactory.createLineBorder(myColor), "Controlli di gioco");
		title.setTitleJustification(TitledBorder.LEFT);
		title.setTitleColor(myColor);
		title.setTitleFont(new Font("Arial", Font.BOLD, 15));
		
		wrapDice.add(Box.createRigidArea(new Dimension(30,0)));
		wrapDice.add(dice);
		dicePane.add(Box.createRigidArea(new Dimension(30,0)));
		dicePane.add(btnPane);
		dicePane.add(Box.createRigidArea(new Dimension(30,0)));
		
		
		wrapDice.add(dicePane);
		
		
		pageStart= new JPanel();
		
		pageStart.setBackground(Color.BLACK);
		
		pageStart.setLayout(new BoxLayout(pageStart, BoxLayout.Y_AXIS));
		
		
		JPanel diceAndBtn = new JPanel();
		diceAndBtn.setBackground(Color.BLACK);
		
		diceAndBtn.add(wrapDice);
		
		diceAndBtn.setBorder(title);
		
				
		pageStart.add(diceAndBtn);
		
		pageStart.add(Box.createRigidArea(new Dimension(0,SPACEBETWSECT)));
		
		JLabel mycards = new JLabel("LE TUE CARTE");
		mycards.setForeground(Color.WHITE);
		mycards.setAlignmentX(CENTER_ALIGNMENT);
		mycards.setFont(new Font("Verdana", Font.ITALIC, 18));
		
		pageStart.add(mycards);
						
		pageStart.add(Box.createRigidArea(new Dimension(0,5)));
		
		JLabel nicknamesLabel = new JLabel("Giocatori");
		nicknamesLabel.setForeground(Color.WHITE);
		nicknamesLabel.setAlignmentX(CENTER_ALIGNMENT);
		nicknamesLabel.setFont(new Font("Verdana", Font.ITALIC, 18));
		
		
		nicknames = new NicknamesArea(myPlayer);
		
		log.printLog("EastPanel: L'area dei nicknames e' stata creata");
		
		nicknames.setEditable(false);
		nicknames.setBackground(Color.DARK_GRAY);
		
		JScrollPane nicknameScrollPane = new JScrollPane(nicknames);
		nicknameScrollPane.setPreferredSize(new Dimension(80,130));
		nicknameScrollPane.setBackground(Color.BLACK);
		nicknameScrollPane.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		
		pageStart.add(nicknamesLabel);
		
		pageStart.add(Box.createRigidArea(new Dimension(0,5)));
		
		pageStart.add(nicknameScrollPane);

		pageStart.add(Box.createRigidArea(new Dimension(0,SPACEBETWSECT)));

		
		JLabel chatLabel = new JLabel("Chat");
		chatLabel.setForeground(Color.WHITE);
		chatLabel.setAlignmentX(CENTER_ALIGNMENT);
		chatLabel.setFont(new Font("Verdana", Font.ITALIC, 18));
		
		pageStart.add(chatLabel);
		
		pageStart.add(Box.createRigidArea(new Dimension(0,5)));
				
		chat = new JTextPane();
		chat.setEditable(false);
		chat.setBackground(Color.LIGHT_GRAY);
		
		JScrollPane chatScrollPane = new JScrollPane(chat);
		chatScrollPane.setPreferredSize(new Dimension(80,150));
		chatScrollPane.setBackground(Color.LIGHT_GRAY);
		chatScrollPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
		
		JPanel center= new JPanel();
		
		center.setBackground(Color.BLACK);

		center.setLayout(new BoxLayout(center, BoxLayout.Y_AXIS));
		
		center.add(chatScrollPane);
		
		
		JPanel inputChatPane=new JPanel();
		inputChatPane.setBackground(Color.LIGHT_GRAY);
		inputChatPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
		
		chatInput = new JTextField("",20);
		chatInput.addKeyListener(this);
		
		chatSendButton = new JButton("Invia");
		chatSendButton.addActionListener(this);                              
		
		
		inputChatPane.add(chatInput);
		inputChatPane.add(chatSendButton);
		
		
		JPanel pageEnd= new JPanel();
		
		pageEnd.setBackground(Color.BLACK);
		
		pageEnd.setLayout(new BoxLayout(pageEnd, BoxLayout.Y_AXIS));

		
		pageEnd.add(inputChatPane);
		
		pageEnd.add(Box.createRigidArea(new Dimension(0,5)));
		
		outsidePane.add(pageStart,BorderLayout.PAGE_START);
		outsidePane.add(center,BorderLayout.CENTER);
		outsidePane.add(pageEnd,BorderLayout.PAGE_END);
		
		outsideSpace.add(Box.createRigidArea(new Dimension(5,0)));
		outsideSpace.add(outsidePane);
		outsideSpace.add(Box.createRigidArea(new Dimension(5,0)));

		add(outsideSpace);
		
		//this.add(outsideSpace,BorderLayout.CENTER);
		
		log.printLog("EastPanel: la chat e' stata creata");
		
		log.printLog("EastPanel: il pannello East e' stato creato");

	}
	
	
	/***
	 * Restituisce l'area nickname contenuta nell'EastPanel
	 * @return vedi descrizione
	 */
	public NicknamesArea getNicknamesArea(){
		
		return nicknames;
	}
	
	
	/** 
	 * Invia un messaggio di chat agli altri host remoti quando viene premuto il tasto invia
	 * 
	 */
	@Override
	public void actionPerformed(ActionEvent evt) {
				
		String text=chatInput.getText();
		
		if(text.equals("")) return;
		
		chatInput.setText(""); // vuota il contenuto del campo di Input della chat		

		log.printLog("EastPanel: invio il mio messaggio di chat agli altri con multicastChatMessage");

		// invio il msg di chat a tutti
				
    	myPlayer.multicastChatMessage(myPlayer.getNickname(),text);
      
		
	}
	
	/**
	 * Visualizza nell'interfaccia grafica le carte che ho in mano
	 * @param cards le carte che mi sono state distribuite
	 */
	public void showMyCard(LinkedList<Card> cards){
		
		// visualizzo le carte che ho in mano
		
		log.printLog("EastPanel: visualizzo le carte che mi sono state distribuite nella mia interfaccia grafica");
		
		JPanel myCard=new JPanel();
				
		myCard.setLayout(new BoxLayout(myCard, BoxLayout.X_AXIS));
				
		myCard.setBackground(Color.BLACK);
								
		JLabel tmpLab;
		
		int i=1,j=4;
		for(Card c : cards){
				tmpLab = new JLabel();
				tmpLab.setIcon (c.getScaledImage(SCALECARD));
				tmpLab.setToolTipText(c.getName());
				myCard.add(tmpLab);
				myCard.add(Box.createRigidArea(new Dimension(SPACEBETWCARDS,0)));

				// righe da 3 carte
				if(i%3==0){
					pageStart.add(myCard,j++);
					pageStart.add(Box.createRigidArea(new Dimension(0,5)),j++);
					myCard=new JPanel();
					myCard.setLayout(new BoxLayout(myCard, BoxLayout.X_AXIS));
					myCard.setBackground(Color.BLACK);
					}
				i++;
				}
				
		pageStart.add(myCard,j++); 
		
		pageStart.add(Box.createRigidArea(new Dimension(0,SPACEBETWSECT)),j);
		
		this.revalidate();
		this.repaint();
		
		log.printLog("EastPanel: aggiunte le carte in mano al player");
		
	}
	
	/** Aggiorna la chat con il mio messaggio inviato o con un messaggio ricevuto 
	 *@param playerName il nickname del player che ha inviato il messaggio
	 *@param text il testo del messaggio 
	 */
	
	public void updateChat(String playerName, String text){
		
		if(text.compareTo("")==0) return;
		else text+="\n";
        StyledDocument doc = chat.getStyledDocument();
        SimpleAttributeSet textStyle = new SimpleAttributeSet();
        SimpleAttributeSet nameStyle = new SimpleAttributeSet();
        SimpleAttributeSet timeStyle = new SimpleAttributeSet();
        
        SimpleDateFormat sDate = new SimpleDateFormat("HH:mm:ss");
        
        
        StyleConstants.setForeground(timeStyle,Color.DARK_GRAY);
        StyleConstants.setFontFamily(timeStyle,"Arial");
        StyleConstants.setFontSize(timeStyle, 14);
        
        StyleConstants.setForeground(nameStyle,myPlayer.getPlayerColor(playerName));
        StyleConstants.setFontFamily(nameStyle,"Courier");
        StyleConstants.setFontSize(nameStyle, 20);
        StyleConstants.setBold(nameStyle, true);
        
        StyleConstants.setForeground(textStyle ,Color.BLACK);
        StyleConstants.setFontFamily(textStyle ,"Arial");
        StyleConstants.setFontSize(textStyle , 18);
        StyleConstants.setBold(textStyle , false);
        
        String tx="";
        String time="("+sDate.format(new Date())+") ";
        
        
        boolean myMsg = false;
        
        if(playerName.equals(myPlayer.getNickname())){
        	tx="Io";
        	myMsg=true;
        }
        else{
        	tx=playerName;
        	myMsg=false;
        }

        if(myMsg)
        	log.printLog("EastPanel: aggiorno la mia chat con il messaggio: "+text+" inviato da me");

        else
        	log.printLog("EastPanel: aggiorno la mia chat con il messaggio: "+text+" inviato da "+tx);
        
        
        try{
        	doc.insertString(doc.getLength(),time,timeStyle);
        	doc.insertString(doc.getLength(), tx+": ",nameStyle);
        	doc.insertString(doc.getLength(),text,textStyle);
        	} catch(BadLocationException exc) {
        		exc.printStackTrace();
        	}
      
		
	}
	
	
	/**
	 * Ferma il timer
	 */
	public void stopTimer(){
		
		
		log.printLog("EastPanel: Fermo il timer che fa lampeggiare i tasti soluzione/ipotesi ed il dado e mostro graficamente questi come non attivi");
		
		if(timer!=null && timer.isRunning())
			timer.stop();
		
		LineBorder b;
		Color borderCol;
		
		b= (LineBorder)dice.getBorder();
		borderCol=b.getLineColor();
		if(borderCol==Color.GREEN){
			dice.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		}
		
		b= (LineBorder)assumptSolBtn.getBorder();
		borderCol=b.getLineColor();
		if(borderCol==Color.GREEN){
			assumptSolBtn.setBorder(BorderFactory.createLineBorder(assumptSolBtn.getBackground(),5));
		}
		
		b= (LineBorder)endTurnBtn.getBorder();
		borderCol=b.getLineColor();
		if(borderCol==Color.GREEN){
			endTurnBtn.setBorder(BorderFactory.createLineBorder(endTurnBtn.getBackground(),5));
		}
	
		
	}
	
	
	/**
	 * Avvia solo il timer del tasto di End Turn
	 */
	public void onlyTimerEndTurn(){
		
		if(timer!=null && timer.isRunning())
			stopTimer();
		
		Cursor handCurs = new Cursor(Cursor.HAND_CURSOR);
		
		endTurnBtn.setEnabled(true);
		endTurnBtn.setCursor(handCurs);
		
		setAssumptSolBtn();
		
		timer = new Timer(500, new TimerListener(false,false,true)); 
		
		timer.start();
		
		
	}
	
	
	/***
	 * Il listener per gestire il timer per evidenziare dado e tasti ipotesi e soluzione
	 *
	 */
	private class TimerListener implements ActionListener {
				
		boolean activeDice=false;
		boolean activeAssumptSol=false;
		boolean activeEndTurn=false;
		
		public TimerListener(boolean activeDice, boolean activeAssumptSol, boolean activeEndTurn){
			this.activeDice=activeDice;
			this.activeAssumptSol=activeAssumptSol;
			this.activeEndTurn=activeEndTurn;
		}
		
		public void actionPerformed(ActionEvent e) {
			
			LineBorder b;
			Color borderCol;
		
			if(activeDice){
				
				b= (LineBorder)dice.getBorder();
				borderCol=b.getLineColor();
				
				if(borderCol==Color.BLACK){
					dice.setBorder(BorderFactory.createLineBorder(Color.GREEN,3));
				}
				else{
					dice.setBorder(BorderFactory.createLineBorder(Color.BLACK));
				}
			}
			
			if(activeAssumptSol){
				
				b= (LineBorder)assumptSolBtn.getBorder();
				borderCol=b.getLineColor();
				
				if(borderCol==assumptSolBtn.getBackground()){
					assumptSolBtn.setBorder(BorderFactory.createLineBorder(Color.GREEN,5));
				}
				else{
					assumptSolBtn.setBorder(BorderFactory.createLineBorder(assumptSolBtn.getBackground(),5));
				}
			}
			
			if(activeEndTurn){
				
				b= (LineBorder)endTurnBtn.getBorder();
				borderCol=b.getLineColor();
				
				if(borderCol==endTurnBtn.getBackground()){
					endTurnBtn.setBorder(BorderFactory.createLineBorder(Color.GREEN,5));
				}
				else{
					endTurnBtn.setBorder(BorderFactory.createLineBorder(endTurnBtn.getBackground(),5));
				}
			}
			
			
		}
	}
	
	
	/**
	 * Disabilita i tasti soluione, ipotesi ed il dado
	 */
	public void disableAllGameBtn(){
		
		log.printLog("EastPanel: disabilito i tasti soluzione/ipotesi ed il dado");
		assumptSolBtn.setEnabled(false);
		assumptSolBtn.setCursor(null);
		endTurnBtn.setEnabled(false);
		endTurnBtn.setCursor(null);
       	dice.setEnabled(false);
       	dice.setCursor(null);
       	
	}
	
	
	/**
	 * Verifica quali bottoni devono essere abilitati e li abilita
	 * @param isDiceThrow true se il dado e' gia' stato tirato, false altrimenti
	 * @param isAssumptionChecked se ho formulato un'ipotesi ed e' appena stata controllata
	 */
	public void enableGameBtn(boolean isDiceThrow,boolean isAssumptionChecked){
		
		
		if(timer!=null && timer.isRunning())
			stopTimer();
				
		log.printLog("EastPanel: abilito i tasti soluzione ipotesi e dado a seconda che questo risulti gia' stato tirato oppure che la" +
				" mia pedina si trovi in una stanza\n" +
				" parametro isDiceThrow="+isDiceThrow+"\n" +
				"la mi apedina e' in una stanza --> "+ myPlayer.getPawn().isInRoom());
		
		boolean activeDice=false;
		boolean activeAssumptSol=true;
		boolean activeEndTurn=true;
		Cursor handCurs = new Cursor(Cursor.HAND_CURSOR);

		endTurnBtn.setEnabled(true);
		endTurnBtn.setCursor(handCurs);		
		
		
		if(isDiceThrow){
			dice.setEnabled(false);
			activeDice=false;
			dice.setCursor(null);
		}
		else{
			dice.setEnabled(true);
			activeDice=true;
			dice.setCursor(handCurs);
		}
		if(!myPlayer.getPawn().isInRoom()){ 
			
			assumptSolBtn.setActionCommand("Soluzione");
			assumptSolBtn.setText(" Soluzione ");
		
		}
		
		else{
			
			if(isAssumptionChecked){
				setSolBtn();
			}
			
			else{
				setAssumptSolBtn();
			}
			
		}
		
		assumptSolBtn.setEnabled(true);
		assumptSolBtn.setCursor(handCurs);		
		
		log.printLog("EastPanel: infine avvio il timer passandogli activeDice="+activeDice+" ,activeAssumptSol="+activeAssumptSol+" ,activeEndTurn="+activeEndTurn);
		
		timer = new Timer(500, new TimerListener(activeDice,activeAssumptSol,activeEndTurn)); 
		
		timer.start();
		
	}
	
	
	/**
	 * Fai apparire nei controlli di gioco il tasto soluzione
	 */
	public void setSolBtn(){
		
		if(assumptSolBtn.getActionCommand().equals("Ipotesi/Soluzione")){
			assumptSolBtn.setActionCommand("Soluzione");
			assumptSolBtn.setText(" Soluzione ");
		}
		
	}
	
	/**
	 * Fai apparire nei controlli di gioco il tasto ipotesi/soluzione
	 */
	public void setAssumptSolBtn(){
		
		if(assumptSolBtn.getActionCommand().equals("Soluzione")){
			assumptSolBtn.setActionCommand("Ipotesi/Soluzione");
			assumptSolBtn.setText(" Ipotesi/Sol ");
		}
		
	}
	
	
	/**
	 * Lancia il dado
	 * @return il valore ottenuto dal lancio del dado
	 */
	public int rollDice(){
		int val = dice.roll();
		dice.setValue(val);
		
		return val;
	}
	
	
	@Override
	public void keyTyped(KeyEvent e) {}
	
	@Override
	public void keyReleased(KeyEvent e) {}
	   
	/**
	 * Invia un messaggio di chat agli altri host remoti quando viene premuto il tasto enter della tastiera
	 * all'interno del campo testo della chat
	 */
	@Override
	public void keyPressed(KeyEvent e) {
		
		int key = e.getKeyCode();
	    
		if (key == KeyEvent.VK_ENTER) {
			
			chatSendButton.doClick();
	        
	        }   	
    }
	
}
